Introduction

This paper will be a survival analysis based on Roman Emperors (from 26 before JC to 395 AD), for which data was found on this website: https://public.opendatasoft.com/explore/dataset/roman-emperors/table/?sort=index

Preparation

Load libraries (survival and the ones I’m used to working with) and import data

library(survival) # for survival analysis
library(data.table) # for data import
library(tidyverse) # for data manipulation
library(lubridate) # because the dates stretch over AD and BC eras, we need lubridate's as_date() to handle negative dates
library(survminer) # for plotting survival curves
library(plotly) # for other plots
# emperors <- fread("https://public.opendatasoft.com/explore/dataset/roman-emperors/download/?format=csv&timezone=Europe/Berlin&use_labels_for_header=true", stringsAsFactors = TRUE, check.names = TRUE) #download file straight from sourcepage
emperors <- fread("roman-emperors.csv", stringsAsFactors = TRUE, check.names = TRUE) #use previously downloaded file

Cleaning & formatting

emperors <- emperors %>% select(-Verif, -Image) %>% arrange(Index)
emperors$Birth <- as.character(emperors$Birth) %>% as_date() 
emperors$Death <- as.character(emperors$Death) %>% as_date()
emperors$Reign.Start <- as.character(emperors$Reign.Start) %>% as_date()
emperors$Reign.End <- as.character(emperors$Reign.End) %>% as_date()

Some of the birth dates (and the first reign start date) take place in BCE, so we need to change them to negative years, which is where the lubridate package comes into play. The indication of whether the date should be modified is in the Notes field.

ref_year <- as.integer(as_date("1/1/1"))
emperors$Birth[grep("BCE", emperors$Notes)] <- as_date(as.integer(emperors$Birth[grep("BCE", emperors$Notes)]) - 2*(as.integer(emperors$Birth[grep("BCE", emperors$Notes)]) - ref_year) - 365)
emperors$Reign.Start[grep("reign.start are BCE", emperors$Notes)] <- as_date(as.integer(emperors$Reign.Start[grep("reign.start are BCE", emperors$Notes)]) - 2*(as.integer(emperors$Reign.Start[grep("reign.start are BCE", emperors$Notes)]) - ref_year) - 365)

Exploration

How did they die?

plot_ly(data = emperors, x = ~Cause, type = "histogram") %>% layout(title = "Causes of death", xaxis = list(title = "Cause"), yaxis = list(title = "Frequency"))

Definition of Survival

We’ll look at Assassination, Captivity and Execution as traumatic ends to their reigns (event = 1), while Natural Causes, Died in Battle and Suicide are more “normal” ways for an emperor’s reign to come to an end (event = 0). We’ll censor on emperors who died after the end of their reign (the ones that abdicated or were deposed without being killed)

emperors$event <- ifelse(emperors$Cause %in% c("Assassination", "Captivity", "Execution"), 1, 0)
emperors$event <- ifelse(emperors$Reign.End < emperors$Death, 0, emperors$event)
emperors <- filter(emperors, Cause != "Unknown" | Reign.End < Death) # Getting rid of the unknown deaths that are not censored

We need to calculate ages.

emperors$age_accession <- interval(emperors$Birth, emperors$Reign.Start) / years(1)
emperors$length_reign <- interval(emperors$Reign.Start, emperors$Reign.End) / years(1)
emperors$age_death <- interval(emperors$Birth, emperors$Death) / years(1)
plot_ly(data = filter(emperors, !is.na(age_death)), type = "histogram", alpha = 0.6) %>%
  add_trace(x = ~age_death, type = "histogram", name = "Age of death")  %>% 
  add_trace(x = ~length_reign, type = "histogram", name = "Length of reign") %>%
  layout(barmode = "overlay", title = "Age of Death & Length of Reign", xaxis = list(title = "Years"), yaxis = list(title = "Frequency")) 

An explicit chart of the lifespan and reign length of all the emperors over time.

p <- plot_ly()
for(i in 1:(nrow(emperors) - 1)){
  p <- add_trace(p, type = "scatter", mode = "lines", # Life line
                 x = c(year(emperors$Birth[i]), 
                           year(emperors$Death[i])),
                 y = c(i, i),
                 line = list(color = "white", width = 5),
                 showlegend = F, hoverinfo = "text",
                 # Create custom hover text
                 text = paste("Name: ", emperors$Name[i], "<br>",
                              "Age: ", round(emperors$age_death[i], 1), "years<br>",
                              "Length of reign: ", round(emperors$length_reign[i], 1), "years<br>")) %>% 
    
    add_trace(type = "scatter", x = c(year(emperors$Reign.Start[i]), 
                                      year(emperors$Reign.End[i])), # Reign line
              y = c(i, i), mode = "lines", line = list(color = "blue", width = 3),
              showlegend = F, hoverinfo = "none") %>%
    
    layout(plot_bgcolor = "#424D5C", paper_bgcolor = "#424D5C",
           font=list(color = "white", size = 12),
           yaxis = list(showgrid = F, tickmode = "array", tickfont = list(size = 7),
                        autorange = "reversed",
                        tickvals = 1:nrow(emperors), ticktext = unique(emperors$Name)),
           xaxis = list(showgrid = F,
                        tickval = min(emperors$Birth, na.rm=T):max(emperors$Death, na.rm=T), title = " <b><i>Date</i></b>", titlefont = list(color= c("#7F9FBD"))),
           title = "Life and reign of Roman emperors")
}
p

Distribution observation

table(emperors$event)

 0  1 
34 32 
plot_ly(data = emperors, x = ~length_reign, type = "histogram", marker = list(color="red")) %>% layout(title = "Distribution of length reign for all emperors", xaxis = list(title = "Years of reign"), yaxis = list(title = "Frequency"))

plot_ly(data = filter(emperors, event == 1), x = ~length_reign, type = "histogram", marker = list(color="purple")) %>% layout(title = "Distribution of length reign for uncensored emperors", xaxis = list(title = "Years of reign"), yaxis = list(title = "Frequency"))

The data is evenly split between events and censoring. Neither of the distributions seem to follow a specific law, so we’ll have to skip the classical statistics, and jump straight to the survival analysis.

Survival Analysis

Kaplan-Meier

The simplest analysis we can look at is the Kaplan-Meier survival curves.

KM <- survfit(Surv(length_reign, event)~1, data=emperors)
KM
Call: survfit(formula = Surv(length_reign, event) ~ 1, data = emperors)

      n  events  median 0.95LCL 0.95UCL 
  66.00   32.00   14.92    6.04      NA 

Median Survival: The first observation is that after almost 15 years, half of the 66 emperors had already been killed.

ggsurvplot(KM, risk.table = TRUE, main = "Kaplan-Meier for emperors' survival", xlab = "Length of reign in years", ylab = "Survival rate")

This plot shows the survival rate of emperors based on their length of reign, with crosses for the emperors that were not killed (censored). The table at the bottom indicates the number of surviving emperors after years of reign from 0 (minimum survival time) to 40 (maximum survival time).

Logrank

There are two large eras covered by the data’s timeframe: the Principate (earlier) and the Dominate (or despotic) eras. Let’s find out if there are significant differences in emperors’ survival expectation between these two eras or not.

table(emperors$Era, emperors$event)
            
              0  1
  Dominate   14  6
  Principate 20 26
logrank <- survdiff(Surv(length_reign, event)~Era, data = emperors)
logrank
Call:
survdiff(formula = Surv(length_reign, event) ~ Era, data = emperors)

                N Observed Expected (O-E)^2/E (O-E)^2/V
Era=Dominate   20        6     11.6      2.73       4.4
Era=Principate 46       26     20.4      1.56       4.4

 Chisq= 4.4  on 1 degrees of freedom, p= 0.036 

The rather low p-value of this logrank test shows us that there seems to be a significant difference, which we’ll investigate further with stratification.

Stratification

To find out in which way the era influences survival, we’ll plot the distinction.

ggsurvplot(survfit(Surv(length_reign, event) ~Era, data=emperors), pval = TRUE, risk.table = TRUE, main = "Emperors' survival by Era (log-log)", fun="cloglog")

We can see already that there is a steep difference in survival rate if we distinguish the 2 eras: emperors were much likely to get killed in the Principate era than in the Dominate era. This finding is reinforced by the parallelism of both curves, in log-log format.

This result is rather surprising, as we know that the Principate era was characterised by an effort on the part of the emperors to preserve the illusion of continuance of the Roman Republic.

We’ll investigate on other possible distinctions that might influence the risk for emperors to get killed. For example, we can wonder if the way the emperor achieved his position (Succession) influences the risk. There are too many categories, so let’s first group some of them together.

emperors$Succession2 <- ifelse(emperors$Succession %in% c("Appointment by Army", "Appointment by Praetorian Guard"), "Appointment by military", ifelse(emperors$Succession %in% c("Appointment by Emperor", "Appointment by Senate"), "Appointment by state", ifelse(emperors$Succession == "Birthright", "Birthright", ifelse(emperors$Succession == "Seized Power", "Seized Power",  "Other"))))
summary(coxph(Surv(length_reign, event) ~Era + Succession2, data = emperors))
Call:
coxph(formula = Surv(length_reign, event) ~ Era + Succession2, 
    data = emperors)

  n= 66, number of events= 32 

                                    coef exp(coef) se(coef)      z Pr(>|z|)  
EraPrincipate                    1.02913   2.79863  0.49705  2.070   0.0384 *
Succession2Appointment by state -0.09463   0.90971  0.68215 -0.139   0.8897  
Succession2Birthright           -1.21307   0.29728  0.52734 -2.300   0.0214 *
Succession2Other                 0.38298   1.46665  1.14179  0.335   0.7373  
Succession2Seized Power         -0.78310   0.45699  0.66021 -1.186   0.2356  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

                                exp(coef) exp(-coef) lower .95 upper .95
EraPrincipate                      2.7986     0.3573    1.0565    7.4138
Succession2Appointment by state    0.9097     1.0993    0.2389    3.4638
Succession2Birthright              0.2973     3.3638    0.1058    0.8357
Succession2Other                   1.4666     0.6818    0.1565   13.7473
Succession2Seized Power            0.4570     2.1882    0.1253    1.6668

Concordance= 0.698  (se = 0.056 )
Rsquare= 0.168   (max possible= 0.963 )
Likelihood ratio test= 12.1  on 5 df,   p=0.03338
Wald test            = 11.2  on 5 df,   p=0.04756
Score (logrank) test = 12.67  on 5 df,   p=0.02671
summary(coxph(Surv(length_reign, event) ~Era + strata(Succession2), data = emperors))
Call:
coxph(formula = Surv(length_reign, event) ~ Era + strata(Succession2), 
    data = emperors)

  n= 66, number of events= 32 

                coef exp(coef) se(coef)     z Pr(>|z|)
EraPrincipate 0.6993    2.0123   0.4776 1.464    0.143

              exp(coef) exp(-coef) lower .95 upper .95
EraPrincipate     2.012     0.4969    0.7892     5.131

Concordance= 0.536  (se = 0.08 )
Rsquare= 0.035   (max possible= 0.886 )
Likelihood ratio test= 2.38  on 1 df,   p=0.1226
Wald test            = 2.14  on 1 df,   p=0.1431
Score (logrank) test = 2.22  on 1 df,   p=0.1362
ggsurvplot(survfit(Surv(length_reign, event) ~ Succession2, data = emperors), pval = TRUE, pval.coord = c(30,0.8), main = "Emperors' survival by way of accessing power", legend.labs = c("Appointment by military", "Appointment by state", "Birthright", "Other", "Seized Power"))

The first detailed model, displays interesting relevance with low p-values indicating that different succession methods imply different risks, while the second more general model does not offer a credible p-value to be followed as-is.

Indeed, plotting the Cox in cloglog we can see that the lines are not parralel, which is why the model as a whole is not so effective.

ggsurvplot(survfit(Surv(length_reign, event) ~ Era + Succession2, data = emperors), pval = TRUE, pval.coord = c(30,-2), fun="cloglog", legend.labs = c("Dominate/Appointment by military", "Dominate/Appointment by state", "Dominate/Birthright", "Dominate/Other", "Dominate/Seized Power","Principate/Appointment by military", "Principate/Appointment by state", "Principate/Birthright", "Principate/Other", "Principate/Seized Power"))

We can conclude from this (none of the lines are parallel) that the model is not accurate because the Cox assumption of proportionality of hazards is not respected: we will not be able to use the coefficients from the model, but we may still consider Succession as a somewhat interesting variable, since adding the Succession to the Era improves the p-value.

We can wonder if the Emperor’s origin plays a role in his popularity in Rome and therefore his survival likelihood.

table(emperors$Birth.Province, emperors$event)
                    
                      0  1
  Africa              0  1
  Dacia Aureliana     0  1
  Dalmatian           1  0
  Gallia Lugdunensis  0  2
  Gallia Narbonensis  1  1
  Hispania            1  0
  Hispania Baetica    2  0
  Italia             11 11
  Libya               1  0
  Mauretania          0  1
  Moesia              3  1
  Moesia Superior     3  0
  Pannonia            6  3
  Pannonia Inferior   1  0
  Phrygia             1  0
  Syria               0  3
  Thrace              1  1
  Unknown             2  7

However, the categories are a little too numerous and therefore too restrictive to be very indicative, so we’ll proceed to some grouping in order to have wider groups.

emperors$Birth.Region <- ifelse(emperors$Birth.Province %in% c("Africa", "Libya", "Mauretania"), "Africa", ifelse(emperors$Birth.Province %in% c("Gallia Lugdunensis", "Gallia Narbonensis"), "Gaul", ifelse(emperors$Birth.Province %in% c("Hispania", "Hispania Baetica"), "Spain", ifelse(emperors$Birth.Province %in% c("Dacia Aureliana", "Dalmatian", "Moesia", "Moesia Superior", "Pannonia", "Pannonia Inferior", "Thrace"), "East Europe", ifelse(emperors$Birth.Province %in% c("Phrygia", "Syria"), "Asia Minor", ifelse(emperors$Birth.Province == "Italia", "Italia", "Unknown"))))))
table(emperors$Birth.Region, emperors$event)
             
               0  1
  Africa       1  2
  Asia Minor   1  3
  East Europe 15  6
  Gaul         1  3
  Italia      11 11
  Spain        3  0
  Unknown      2  7

It will be easier to work with 7 levels than 18.

region <- survfit(Surv(length_reign, event) ~Birth.Region, data=emperors)
summary(region)
Call: survfit(formula = Surv(length_reign, event) ~ Birth.Region, data = emperors)

                Birth.Region=Africa 
  time n.risk n.event survival std.err lower 95% CI upper 95% CI
 0.167      3       1    0.667   0.272       0.2995            1
 1.159      2       1    0.333   0.272       0.0673            1

                Birth.Region=Asia Minor 
  time n.risk n.event survival std.err lower 95% CI upper 95% CI
  3.76      3       1    0.667   0.272       0.2995            1
  5.63      2       1    0.333   0.272       0.0673            1
 13.01      1       1    0.000     NaN           NA           NA

                Birth.Region=East Europe 
  time n.risk n.event survival std.err lower 95% CI upper 95% CI
  2.25     15       1    0.933  0.0644        0.815        1.000
  3.24     14       1    0.867  0.0878        0.711        1.000
  5.00     12       1    0.794  0.1061        0.612        1.000
  6.04     10       1    0.715  0.1216        0.512        0.998
 12.73      8       1    0.626  0.1353        0.409        0.956
 16.06      5       1    0.501  0.1557        0.272        0.921

                Birth.Region=Gaul 
  time n.risk n.event survival std.err lower 95% CI upper 95% CI
  2.61      3       1    0.667   0.272       0.2995            1
 13.72      2       1    0.333   0.272       0.0673            1
 19.27      1       1    0.000     NaN           NA           NA

                Birth.Region=Italia 
   time n.risk n.event survival std.err lower 95% CI upper 95% CI
  0.236     22       1    0.955  0.0444        0.871        1.000
  0.260     20       1    0.907  0.0628        0.792        1.000
  0.605     19       1    0.859  0.0755        0.723        1.000
  0.677     18       1    0.811  0.0851        0.661        0.996
  2.167     15       1    0.757  0.0950        0.592        0.968
  2.984     13       1    0.699  0.1041        0.522        0.936
  3.855     12       1    0.641  0.1105        0.457        0.898
 15.011      7       1    0.549  0.1271        0.349        0.864
 15.997      6       1    0.458  0.1349        0.257        0.816
 22.490      3       1    0.305  0.1536        0.114        0.819
 39.668      1       1    0.000     NaN           NA           NA

                Birth.Region=Spain 
     time n.risk n.event survival std.err lower 95% CI upper 95% CI

                Birth.Region=Unknown 
    time n.risk n.event survival std.err lower 95% CI upper 95% CI
  0.0575      9       1    0.889   0.105       0.7056        1.000
  0.2521      8       1    0.778   0.139       0.5485        1.000
  0.2685      7       2    0.556   0.166       0.3097        0.997
  2.3770      4       1    0.417   0.173       0.1847        0.940
  6.0000      3       1    0.278   0.162       0.0888        0.869
 14.9180      1       1    0.000     NaN           NA           NA
ggsurvplot(region, pval = TRUE, pval.coord = c(30,0.9), palette = c(c("#00EE00", "#0000EE", "#CD0000", "#BF3EFF", "#EEEE00", "#00FFFF", "#EE9A00")), main = "Emperors' survival by Province of origin", legend.labs = c("Africa","Asia Minor", "East Europe", "Gaul", "Italia", "Spain", "Unknown"))

Here we can see the survival curves based on the region of origin. There is definitively some impact, based on the low p-value, but the lines themselves are not that indicative (in log-log, they are not parallel), so we won’t be using the information as such.

Looking at the age emperors had at the time they took power. As for the origin, we’ll have to categorize first.

emperors$age_accession2 <- ifelse(emperors$age_accession>60, "61+", ifelse(emperors$age_accession>40, "41-60", ifelse(emperors$age_accession>30, "31-40", ifelse(emperors$age_accession<30, "30-", "Unknown"))))
age_access <- survfit(Surv(length_reign, event) ~age_accession2, data=emperors)
summary(age_access)
Call: survfit(formula = Surv(length_reign, event) ~ age_accession2, 
    data = emperors)

4 observations deleted due to missingness 
                age_accession2=30- 
  time n.risk n.event survival std.err lower 95% CI upper 95% CI
  2.61     16       1    0.938  0.0605       0.8261        1.000
  2.98     15       1    0.875  0.0827       0.7271        1.000
  3.76     13       1    0.808  0.1000       0.6336        1.000
  3.85     12       1    0.740  0.1121       0.5503        0.996
  6.00     10       1    0.666  0.1229       0.4642        0.957
 12.73      9       1    0.592  0.1297       0.3857        0.910
 13.01      8       1    0.518  0.1329       0.3135        0.857
 15.01      6       1    0.432  0.1360       0.2330        0.800
 16.00      5       1    0.346  0.1334       0.1621        0.736
 16.06      4       1    0.259  0.1249       0.1007        0.667
 19.27      2       1    0.130  0.1109       0.0242        0.693

                age_accession2=31-40 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI
 14.9      7       1    0.857   0.132        0.633            1
 39.7      1       1    0.000     NaN           NA           NA

                age_accession2=41-60 
    time n.risk n.event survival std.err lower 95% CI upper 95% CI
  0.0575     23       1    0.957  0.0425       0.8767        1.000
  0.1671     22       1    0.913  0.0588       0.8049        1.000
  0.6767     21       1    0.870  0.0702       0.7423        1.000
  1.1589     19       1    0.824  0.0801       0.6809        0.997
  2.1671     15       1    0.769  0.0916       0.6087        0.971
  2.2521     14       1    0.714  0.1002       0.5422        0.940
  5.0000     13       1    0.659  0.1065       0.4801        0.905
  5.6274     12       1    0.604  0.1109       0.4216        0.866
  6.0438     10       1    0.544  0.1151       0.3591        0.823
 13.7151      7       1    0.466  0.1221       0.2789        0.779
 22.4904      2       1    0.233  0.1757       0.0532        1.000

                age_accession2=61+ 
  time n.risk n.event survival std.err lower 95% CI upper 95% CI
 0.236      9       1    0.889   0.105       0.7056        1.000
 0.260      8       1    0.778   0.139       0.5485        1.000
 0.268      7       2    0.556   0.166       0.3097        0.997
 0.605      5       1    0.444   0.166       0.2141        0.923
 3.238      2       1    0.222   0.178       0.0464        1.000
ggsurvplot(age_access, pval = TRUE, pval.coord = c(30,0.6), main = "Emperors' survival by age at beginning of reign in log-log", legend.labs = c("30 & less", "31-40", "41-60", "61 and above"), fun="cloglog")

Here the p-value is much lower even, and the lines barely cross which implies that we’re closer to a model we could use.

Cox regression Model

library(networkD3)

Distribution of emperors by Dynasty

simpleNetwork(select(emperors, Name, Dynasty), fontSize = 18, nodeColour = "red")

To find out the difference of survival chance between dynasties, we can use the Cox model. This will compare all dynasties with the first one. By default, the first one in alphabetical order will be used for comparison. Here, we’ll change the order, so that the Flavian dynasty comes first, as it is the only one that had a 50-50 survival rate.

emperors$Dynasty = factor(emperors$Dynasty,levels(emperors$Dynasty)[c(2,1,3:8)])
summary(coxph(formula = Surv(length_reign, event) ~ Dynasty, data = emperors))
Loglik converged before variable  6 ; beta may be infinite. 
Call:
coxph(formula = Surv(length_reign, event) ~ Dynasty, data = emperors)

  n= 66, number of events= 32 

                            coef  exp(coef)   se(coef)      z Pr(>|z|)  
DynastyConstantinian  -1.160e+00  3.134e-01  7.480e-01 -1.551   0.1208  
DynastyGordian         3.898e-01  1.477e+00  6.577e-01  0.593   0.5534  
DynastyJulio-Claudian -1.053e+00  3.490e-01  8.502e-01 -1.238   0.2157  
DynastyNerva-Antonine -2.476e+00  8.410e-02  1.171e+00 -2.114   0.0345 *
DynastySeveran         7.820e-02  1.081e+00  7.020e-01  0.111   0.9113  
DynastyTheodosian     -1.808e+01  1.404e-08  6.563e+03 -0.003   0.9978  
DynastyValentinian    -1.743e+00  1.750e-01  1.163e+00 -1.498   0.1340  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

                      exp(coef) exp(-coef) lower .95 upper .95
DynastyConstantinian  3.134e-01  3.191e+00  0.072341    1.3575
DynastyGordian        1.477e+00  6.772e-01  0.406893    5.3593
DynastyJulio-Claudian 3.490e-01  2.865e+00  0.065944    1.8474
DynastyNerva-Antonine 8.410e-02  1.189e+01  0.008469    0.8352
DynastySeveran        1.081e+00  9.248e-01  0.273187    4.2802
DynastyTheodosian     1.404e-08  7.125e+07  0.000000       Inf
DynastyValentinian    1.750e-01  5.714e+00  0.017907    1.7106

Concordance= 0.735  (se = 0.058 )
Rsquare= 0.285   (max possible= 0.963 )
Likelihood ratio test= 22.16  on 7 df,   p=0.002382
Wald test            = 16.02  on 7 df,   p=0.02493
Score (logrank) test = 21.88  on 7 df,   p=0.002667

This shows us first that the influence of dynasty on survival chances is significant (p-value 0.02493), and that compared to the Flavian dynasty, emperors in the Constantinian dynasty had 0.31 times more chance to survive (+/- 3.19). Still compared to the Flavian, Nerva-Antonine had a very small chance to be killed at 0.0841 (+/- 1.189).

Multiple Covariates

Now, let’s look at the three variables of Succession, Era and Age at accession (with redefined categories as seen above), and try to identify the best explicative model for emperors’ survival.

To study the covariates, we need to use the Cox proportional hazards regression model. The model, and the stepwise algorithm, only works with non-missing values, so I’ll make a selection of the variables to consider, and remove the rows with missing values.

The result of the Cox model and step algorithm (which went through 16 iterations starting with no variable, then adding them one by one) is a predictor based on 8 variables, with low p-values on all tests, indicating that we can safely discard the null hypothesis (that the 8 variables chosen by the stepwise algorithm do not significantly impact chances of survival).

This gives enough confidence to chose the model for the last step of this paper: # Prediction To make a prediction, we need to split the data in 2 parts, one to train the model, the other to test it.

## 75% of the sample size
smp_size <- floor(0.7 * nrow(emperors))
## set the seed to make your partition reproductible
set.seed(24)
train_ind <- sample(seq_len(nrow(emperors)), size = smp_size)
train <- emperors[train_ind, ]
test <- emperors[-train_ind, ]

Here I’ve decided to train the model on 80% of the data (46 emperors), and make the prediction on the 20 left.

Let’s only keep the useful variables in the two data.frames, and remove the rows with NA values in train.

test <- test %>% select(Name, Succession2, Era, age_accession2, length_reign, event)
train <- train %>% select(Succession2, Era, age_accession2, length_reign, event)
train <- filter(train, complete.cases(train))
model <- coxph(Surv(length_reign, event) ~ . , data = train)
models <- step(model, direction="forward")
Start:  AIC=130.45
Surv(length_reign, event) ~ Succession2 + Era + age_accession2

Now that the model is train, we just need to use it to generate the predictions, and compare the predicted value with the true vale in the “event” column.

LS0tDQp0aXRsZTogIlJvbWFuIGVtcGVyb3JzLCBhIFN1cnZpdmFsIEFuYWx5c2lzIg0KYXV0aG9yOiAiTGF1cmVudCBCZXJkZXIiDQpvdXRwdXQ6DQogIHdvcmRfZG9jdW1lbnQ6DQogICAgZmlnX2hlaWdodDogOA0KICAgIGZpZ193aWR0aDogMTINCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzDQogICAgdG9jOiB5ZXMNCiAgaHRtbF9ub3RlYm9vazoNCiAgICBmaWdfd2lkdGg6IDEyDQogICAgaGlnaGxpZ2h0OiBweWdtZW50cw0KICAgIHRoZW1lOiByZWFkYWJsZQ0KICAgIHRvYzogeWVzDQphbHdheXNfYWxsb3dfaHRtbDogeWVzDQotLS0NCiMgSW50cm9kdWN0aW9uDQoNClRoaXMgcGFwZXIgd2lsbCBiZSBhIHN1cnZpdmFsIGFuYWx5c2lzIGJhc2VkIG9uIFJvbWFuIEVtcGVyb3JzIChmcm9tIDI2IGJlZm9yZSBKQyB0byAzOTUgQUQpLCBmb3Igd2hpY2ggZGF0YSB3YXMgZm91bmQgb24gdGhpcyB3ZWJzaXRlOiBodHRwczovL3B1YmxpYy5vcGVuZGF0YXNvZnQuY29tL2V4cGxvcmUvZGF0YXNldC9yb21hbi1lbXBlcm9ycy90YWJsZS8/c29ydD1pbmRleA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCnNldHdkKCJDOi9Vc2Vycy9nYWxkby9PbmVEcml2ZS9PbmVEcml2ZS1Eb2N1bWVudHMvRFNUSS8xNSAtIFN1cnZpdmFsIEFuYWx5c2lzIHVzaW5nIFIvU3Vydml2YWxSb21hbkVtcGVyb3JzIikNCmBgYA0KIyMgUHJlcGFyYXRpb24NCkxvYWQgbGlicmFyaWVzIChzdXJ2aXZhbCBhbmQgdGhlIG9uZXMgSSdtIHVzZWQgdG8gd29ya2luZyB3aXRoKSBhbmQgaW1wb3J0IGRhdGENCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShzdXJ2aXZhbCkgIyBmb3Igc3Vydml2YWwgYW5hbHlzaXMNCmxpYnJhcnkoZGF0YS50YWJsZSkgIyBmb3IgZGF0YSBpbXBvcnQNCmxpYnJhcnkodGlkeXZlcnNlKSAjIGZvciBkYXRhIG1hbmlwdWxhdGlvbg0KbGlicmFyeShsdWJyaWRhdGUpICMgYmVjYXVzZSB0aGUgZGF0ZXMgc3RyZXRjaCBvdmVyIEFEIGFuZCBCQyBlcmFzLCB3ZSBuZWVkIGx1YnJpZGF0ZSdzIGFzX2RhdGUoKSB0byBoYW5kbGUgbmVnYXRpdmUgZGF0ZXMNCmxpYnJhcnkoc3Vydm1pbmVyKSAjIGZvciBwbG90dGluZyBzdXJ2aXZhbCBjdXJ2ZXMNCmxpYnJhcnkocGxvdGx5KSAjIGZvciBvdGhlciBwbG90cw0KDQojIGVtcGVyb3JzIDwtIGZyZWFkKCJodHRwczovL3B1YmxpYy5vcGVuZGF0YXNvZnQuY29tL2V4cGxvcmUvZGF0YXNldC9yb21hbi1lbXBlcm9ycy9kb3dubG9hZC8/Zm9ybWF0PWNzdiZ0aW1lem9uZT1FdXJvcGUvQmVybGluJnVzZV9sYWJlbHNfZm9yX2hlYWRlcj10cnVlIiwgc3RyaW5nc0FzRmFjdG9ycyA9IFRSVUUsIGNoZWNrLm5hbWVzID0gVFJVRSkgI2Rvd25sb2FkIGZpbGUgc3RyYWlnaHQgZnJvbSBzb3VyY2VwYWdlDQplbXBlcm9ycyA8LSBmcmVhZCgicm9tYW4tZW1wZXJvcnMuY3N2Iiwgc3RyaW5nc0FzRmFjdG9ycyA9IFRSVUUsIGNoZWNrLm5hbWVzID0gVFJVRSkgI3VzZSBwcmV2aW91c2x5IGRvd25sb2FkZWQgZmlsZQ0KYGBgDQoNCl9fQ2xlYW5pbmcgJiBmb3JtYXR0aW5nX18NCmBgYHtyfQ0KZW1wZXJvcnMgPC0gZW1wZXJvcnMgJT4lIHNlbGVjdCgtVmVyaWYsIC1JbWFnZSkgJT4lIGFycmFuZ2UoSW5kZXgpDQoNCmVtcGVyb3JzJEJpcnRoIDwtIGFzLmNoYXJhY3RlcihlbXBlcm9ycyRCaXJ0aCkgJT4lIGFzX2RhdGUoKSANCmVtcGVyb3JzJERlYXRoIDwtIGFzLmNoYXJhY3RlcihlbXBlcm9ycyREZWF0aCkgJT4lIGFzX2RhdGUoKQ0KZW1wZXJvcnMkUmVpZ24uU3RhcnQgPC0gYXMuY2hhcmFjdGVyKGVtcGVyb3JzJFJlaWduLlN0YXJ0KSAlPiUgYXNfZGF0ZSgpDQplbXBlcm9ycyRSZWlnbi5FbmQgPC0gYXMuY2hhcmFjdGVyKGVtcGVyb3JzJFJlaWduLkVuZCkgJT4lIGFzX2RhdGUoKQ0KYGBgDQoNClNvbWUgb2YgdGhlIGJpcnRoIGRhdGVzIChhbmQgdGhlIGZpcnN0IHJlaWduIHN0YXJ0IGRhdGUpIHRha2UgcGxhY2UgaW4gQkNFLCBzbyB3ZSBuZWVkIHRvIGNoYW5nZSB0aGVtIHRvIG5lZ2F0aXZlIHllYXJzLCB3aGljaCBpcyB3aGVyZSB0aGUgbHVicmlkYXRlIHBhY2thZ2UgY29tZXMgaW50byBwbGF5LiBUaGUgaW5kaWNhdGlvbiBvZiB3aGV0aGVyIHRoZSBkYXRlIHNob3VsZCBiZSBtb2RpZmllZCBpcyBpbiB0aGUgTm90ZXMgZmllbGQuDQpgYGB7cn0NCnJlZl95ZWFyIDwtIGFzLmludGVnZXIoYXNfZGF0ZSgiMS8xLzEiKSkNCg0KZW1wZXJvcnMkQmlydGhbZ3JlcCgiQkNFIiwgZW1wZXJvcnMkTm90ZXMpXSA8LSBhc19kYXRlKGFzLmludGVnZXIoZW1wZXJvcnMkQmlydGhbZ3JlcCgiQkNFIiwgZW1wZXJvcnMkTm90ZXMpXSkgLSAyKihhcy5pbnRlZ2VyKGVtcGVyb3JzJEJpcnRoW2dyZXAoIkJDRSIsIGVtcGVyb3JzJE5vdGVzKV0pIC0gcmVmX3llYXIpIC0gMzY1KQ0KDQplbXBlcm9ycyRSZWlnbi5TdGFydFtncmVwKCJyZWlnbi5zdGFydCBhcmUgQkNFIiwgZW1wZXJvcnMkTm90ZXMpXSA8LSBhc19kYXRlKGFzLmludGVnZXIoZW1wZXJvcnMkUmVpZ24uU3RhcnRbZ3JlcCgicmVpZ24uc3RhcnQgYXJlIEJDRSIsIGVtcGVyb3JzJE5vdGVzKV0pIC0gMiooYXMuaW50ZWdlcihlbXBlcm9ycyRSZWlnbi5TdGFydFtncmVwKCJyZWlnbi5zdGFydCBhcmUgQkNFIiwgZW1wZXJvcnMkTm90ZXMpXSkgLSByZWZfeWVhcikgLSAzNjUpDQoNCmBgYA0KDQojIyBFeHBsb3JhdGlvbg0KSG93IGRpZCB0aGV5IGRpZT8NCmBgYHtyfQ0KcGxvdF9seShkYXRhID0gZW1wZXJvcnMsIHggPSB+Q2F1c2UsIHR5cGUgPSAiaGlzdG9ncmFtIikgJT4lIGxheW91dCh0aXRsZSA9ICJDYXVzZXMgb2YgZGVhdGgiLCB4YXhpcyA9IGxpc3QodGl0bGUgPSAiQ2F1c2UiKSwgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkZyZXF1ZW5jeSIpKQ0KYGBgDQoNCiMjIERlZmluaXRpb24gb2YgU3Vydml2YWwNCg0KV2UnbGwgbG9vayBhdCAqKkFzc2Fzc2luYXRpb24qKiwgKipDYXB0aXZpdHkqKiBhbmQgKipFeGVjdXRpb24qKiBhcyB0cmF1bWF0aWMgZW5kcyB0byB0aGVpciByZWlnbnMgKGV2ZW50ID0gMSksIHdoaWxlIE5hdHVyYWwgQ2F1c2VzLCBEaWVkIGluIEJhdHRsZSBhbmQgU3VpY2lkZSBhcmUgbW9yZSAibm9ybWFsIiB3YXlzIGZvciBhbiBlbXBlcm9yJ3MgcmVpZ24gdG8gY29tZSB0byBhbiBlbmQgKGV2ZW50ID0gMCkuIFdlJ2xsIGNlbnNvciBvbiBlbXBlcm9ycyB3aG8gZGllZCBhZnRlciB0aGUgZW5kIG9mIHRoZWlyIHJlaWduICh0aGUgb25lcyB0aGF0IGFiZGljYXRlZCBvciB3ZXJlIGRlcG9zZWQgd2l0aG91dCBiZWluZyBraWxsZWQpDQpgYGB7cn0NCmVtcGVyb3JzJGV2ZW50IDwtIGlmZWxzZShlbXBlcm9ycyRDYXVzZSAlaW4lIGMoIkFzc2Fzc2luYXRpb24iLCAiQ2FwdGl2aXR5IiwgIkV4ZWN1dGlvbiIpLCAxLCAwKQ0KZW1wZXJvcnMkZXZlbnQgPC0gaWZlbHNlKGVtcGVyb3JzJFJlaWduLkVuZCA8IGVtcGVyb3JzJERlYXRoLCAwLCBlbXBlcm9ycyRldmVudCkNCg0KZW1wZXJvcnMgPC0gZmlsdGVyKGVtcGVyb3JzLCBDYXVzZSAhPSAiVW5rbm93biIgfCBSZWlnbi5FbmQgPCBEZWF0aCkgIyBHZXR0aW5nIHJpZCBvZiB0aGUgdW5rbm93biBkZWF0aHMgdGhhdCBhcmUgbm90IGNlbnNvcmVkDQpgYGANCg0KDQpXZSBuZWVkIHRvIGNhbGN1bGF0ZSBhZ2VzLg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQplbXBlcm9ycyRhZ2VfYWNjZXNzaW9uIDwtIGludGVydmFsKGVtcGVyb3JzJEJpcnRoLCBlbXBlcm9ycyRSZWlnbi5TdGFydCkgLyB5ZWFycygxKQ0KZW1wZXJvcnMkbGVuZ3RoX3JlaWduIDwtIGludGVydmFsKGVtcGVyb3JzJFJlaWduLlN0YXJ0LCBlbXBlcm9ycyRSZWlnbi5FbmQpIC8geWVhcnMoMSkNCmVtcGVyb3JzJGFnZV9kZWF0aCA8LSBpbnRlcnZhbChlbXBlcm9ycyRCaXJ0aCwgZW1wZXJvcnMkRGVhdGgpIC8geWVhcnMoMSkNCg0KcGxvdF9seShkYXRhID0gZmlsdGVyKGVtcGVyb3JzLCAhaXMubmEoYWdlX2RlYXRoKSksIHR5cGUgPSAiaGlzdG9ncmFtIiwgYWxwaGEgPSAwLjYpICU+JQ0KICBhZGRfdHJhY2UoeCA9IH5hZ2VfZGVhdGgsIHR5cGUgPSAiaGlzdG9ncmFtIiwgbmFtZSA9ICJBZ2Ugb2YgZGVhdGgiKSAgJT4lIA0KICBhZGRfdHJhY2UoeCA9IH5sZW5ndGhfcmVpZ24sIHR5cGUgPSAiaGlzdG9ncmFtIiwgbmFtZSA9ICJMZW5ndGggb2YgcmVpZ24iKSAlPiUNCiAgbGF5b3V0KGJhcm1vZGUgPSAib3ZlcmxheSIsIHRpdGxlID0gIkFnZSBvZiBEZWF0aCAmIExlbmd0aCBvZiBSZWlnbiIsIHhheGlzID0gbGlzdCh0aXRsZSA9ICJZZWFycyIpLCB5YXhpcyA9IGxpc3QodGl0bGUgPSAiRnJlcXVlbmN5IikpIA0KYGBgDQoNCkFuIGV4cGxpY2l0IGNoYXJ0IG9mIHRoZSBsaWZlc3BhbiBhbmQgcmVpZ24gbGVuZ3RoIG9mIGFsbCB0aGUgZW1wZXJvcnMgb3ZlciB0aW1lLg0KYGBge3IsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnAgPC0gcGxvdF9seSgpDQpmb3IoaSBpbiAxOihucm93KGVtcGVyb3JzKSAtIDEpKXsNCiAgcCA8LSBhZGRfdHJhY2UocCwgdHlwZSA9ICJzY2F0dGVyIiwgbW9kZSA9ICJsaW5lcyIsICMgTGlmZSBsaW5lDQogICAgICAgICAgICAgICAgIHggPSBjKHllYXIoZW1wZXJvcnMkQmlydGhbaV0pLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXIoZW1wZXJvcnMkRGVhdGhbaV0pKSwNCiAgICAgICAgICAgICAgICAgeSA9IGMoaSwgaSksDQogICAgICAgICAgICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gIndoaXRlIiwgd2lkdGggPSA1KSwNCiAgICAgICAgICAgICAgICAgc2hvd2xlZ2VuZCA9IEYsIGhvdmVyaW5mbyA9ICJ0ZXh0IiwNCiAgICAgICAgICAgICAgICAgIyBDcmVhdGUgY3VzdG9tIGhvdmVyIHRleHQNCiAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJOYW1lOiAiLCBlbXBlcm9ycyROYW1lW2ldLCAiPGJyPiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWdlOiAiLCByb3VuZChlbXBlcm9ycyRhZ2VfZGVhdGhbaV0sIDEpLCAieWVhcnM8YnI+IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMZW5ndGggb2YgcmVpZ246ICIsIHJvdW5kKGVtcGVyb3JzJGxlbmd0aF9yZWlnbltpXSwgMSksICJ5ZWFyczxicj4iKSkgJT4lIA0KICAgIA0KICAgIGFkZF90cmFjZSh0eXBlID0gInNjYXR0ZXIiLCB4ID0gYyh5ZWFyKGVtcGVyb3JzJFJlaWduLlN0YXJ0W2ldKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXIoZW1wZXJvcnMkUmVpZ24uRW5kW2ldKSksICMgUmVpZ24gbGluZQ0KICAgICAgICAgICAgICB5ID0gYyhpLCBpKSwgbW9kZSA9ICJsaW5lcyIsIGxpbmUgPSBsaXN0KGNvbG9yID0gImJsdWUiLCB3aWR0aCA9IDMpLA0KICAgICAgICAgICAgICBzaG93bGVnZW5kID0gRiwgaG92ZXJpbmZvID0gIm5vbmUiKSAlPiUNCiAgICANCg0KICAgIGxheW91dChwbG90X2JnY29sb3IgPSAiIzQyNEQ1QyIsIHBhcGVyX2JnY29sb3IgPSAiIzQyNEQ1QyIsDQogICAgICAgICAgIGZvbnQ9bGlzdChjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSAxMiksDQogICAgICAgICAgIHlheGlzID0gbGlzdChzaG93Z3JpZCA9IEYsIHRpY2ttb2RlID0gImFycmF5IiwgdGlja2ZvbnQgPSBsaXN0KHNpemUgPSA3KSwNCiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9yYW5nZSA9ICJyZXZlcnNlZCIsDQogICAgICAgICAgICAgICAgICAgICAgICB0aWNrdmFscyA9IDE6bnJvdyhlbXBlcm9ycyksIHRpY2t0ZXh0ID0gdW5pcXVlKGVtcGVyb3JzJE5hbWUpKSwNCiAgICAgICAgICAgeGF4aXMgPSBsaXN0KHNob3dncmlkID0gRiwNCiAgICAgICAgICAgICAgICAgICAgICAgIHRpY2t2YWwgPSBtaW4oZW1wZXJvcnMkQmlydGgsIG5hLnJtPVQpOm1heChlbXBlcm9ycyREZWF0aCwgbmEucm09VCksIHRpdGxlID0gIiA8Yj48aT5EYXRlPC9pPjwvYj4iLCB0aXRsZWZvbnQgPSBsaXN0KGNvbG9yPSBjKCIjN0Y5RkJEIikpKSwNCiAgICAgICAgICAgdGl0bGUgPSAiTGlmZSBhbmQgcmVpZ24gb2YgUm9tYW4gZW1wZXJvcnMiKQ0KfQ0KDQpwDQoNCmBgYA0KDQoNCiMjIERpc3RyaWJ1dGlvbiBvYnNlcnZhdGlvbg0KYGBge3J9DQp0YWJsZShlbXBlcm9ycyRldmVudCkNCg0KcGxvdF9seShkYXRhID0gZW1wZXJvcnMsIHggPSB+bGVuZ3RoX3JlaWduLCB0eXBlID0gImhpc3RvZ3JhbSIsIG1hcmtlciA9IGxpc3QoY29sb3I9InJlZCIpKSAlPiUgbGF5b3V0KHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBvZiBsZW5ndGggcmVpZ24gZm9yIGFsbCBlbXBlcm9ycyIsIHhheGlzID0gbGlzdCh0aXRsZSA9ICJZZWFycyBvZiByZWlnbiIpLCB5YXhpcyA9IGxpc3QodGl0bGUgPSAiRnJlcXVlbmN5IikpDQpwbG90X2x5KGRhdGEgPSBmaWx0ZXIoZW1wZXJvcnMsIGV2ZW50ID09IDEpLCB4ID0gfmxlbmd0aF9yZWlnbiwgdHlwZSA9ICJoaXN0b2dyYW0iLCBtYXJrZXIgPSBsaXN0KGNvbG9yPSJwdXJwbGUiKSkgJT4lIGxheW91dCh0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgbGVuZ3RoIHJlaWduIGZvciB1bmNlbnNvcmVkIGVtcGVyb3JzIiwgeGF4aXMgPSBsaXN0KHRpdGxlID0gIlllYXJzIG9mIHJlaWduIiksIHlheGlzID0gbGlzdCh0aXRsZSA9ICJGcmVxdWVuY3kiKSkNCmBgYA0KVGhlIGRhdGEgaXMgZXZlbmx5IHNwbGl0IGJldHdlZW4gZXZlbnRzIGFuZCBjZW5zb3JpbmcuDQpOZWl0aGVyIG9mIHRoZSBkaXN0cmlidXRpb25zIHNlZW0gdG8gZm9sbG93IGEgc3BlY2lmaWMgbGF3LCBzbyB3ZSdsbCBoYXZlIHRvIHNraXAgdGhlIGNsYXNzaWNhbCBzdGF0aXN0aWNzLCBhbmQganVtcCBzdHJhaWdodCB0byB0aGUgc3Vydml2YWwgYW5hbHlzaXMuDQoNCiMgU3Vydml2YWwgQW5hbHlzaXMNCiMjIEthcGxhbi1NZWllcg0KVGhlIHNpbXBsZXN0IGFuYWx5c2lzIHdlIGNhbiBsb29rIGF0IGlzIHRoZSBLYXBsYW4tTWVpZXIgc3Vydml2YWwgY3VydmVzLg0KDQpgYGB7cn0NCktNIDwtIHN1cnZmaXQoU3VydihsZW5ndGhfcmVpZ24sIGV2ZW50KX4xLCBkYXRhPWVtcGVyb3JzKQ0KS00NCmBgYA0KKk1lZGlhbiBTdXJ2aXZhbDoqIFRoZSBmaXJzdCBvYnNlcnZhdGlvbiBpcyB0aGF0IGFmdGVyIGFsbW9zdCAxNSB5ZWFycywgaGFsZiBvZiB0aGUgNjYgZW1wZXJvcnMgaGFkIGFscmVhZHkgYmVlbiBraWxsZWQuDQoNCmBgYHtyfQ0KZ2dzdXJ2cGxvdChLTSwgcmlzay50YWJsZSA9IFRSVUUsIG1haW4gPSAiS2FwbGFuLU1laWVyIGZvciBlbXBlcm9ycycgc3Vydml2YWwiLCB4bGFiID0gIkxlbmd0aCBvZiByZWlnbiBpbiB5ZWFycyIsIHlsYWIgPSAiU3Vydml2YWwgcmF0ZSIpDQpgYGANCg0KVGhpcyBwbG90IHNob3dzIHRoZSBzdXJ2aXZhbCByYXRlIG9mIGVtcGVyb3JzIGJhc2VkIG9uIHRoZWlyIGxlbmd0aCBvZiByZWlnbiwgd2l0aCBjcm9zc2VzIGZvciB0aGUgZW1wZXJvcnMgdGhhdCB3ZXJlIG5vdCBraWxsZWQgKGNlbnNvcmVkKS4NClRoZSB0YWJsZSBhdCB0aGUgYm90dG9tIGluZGljYXRlcyB0aGUgbnVtYmVyIG9mIHN1cnZpdmluZyBlbXBlcm9ycyBhZnRlciB5ZWFycyBvZiByZWlnbiBmcm9tIDAgKG1pbmltdW0gc3Vydml2YWwgdGltZSkgdG8gNDAgKG1heGltdW0gc3Vydml2YWwgdGltZSkuDQoNCiMjIExvZ3JhbmsNClRoZXJlIGFyZSB0d28gbGFyZ2UgZXJhcyBjb3ZlcmVkIGJ5IHRoZSBkYXRhJ3MgdGltZWZyYW1lOiB0aGUgUHJpbmNpcGF0ZSAoZWFybGllcikgYW5kIHRoZSBEb21pbmF0ZSAob3IgZGVzcG90aWMpIGVyYXMuIExldCdzIGZpbmQgb3V0IGlmIHRoZXJlIGFyZSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBpbiBlbXBlcm9ycycgc3Vydml2YWwgZXhwZWN0YXRpb24gYmV0d2VlbiB0aGVzZSB0d28gZXJhcyBvciBub3QuDQpgYGB7cn0NCnRhYmxlKGVtcGVyb3JzJEVyYSwgZW1wZXJvcnMkZXZlbnQpDQpsb2dyYW5rIDwtIHN1cnZkaWZmKFN1cnYobGVuZ3RoX3JlaWduLCBldmVudCl+RXJhLCBkYXRhID0gZW1wZXJvcnMpDQpsb2dyYW5rDQpgYGANClRoZSByYXRoZXIgbG93IHAtdmFsdWUgb2YgdGhpcyBsb2dyYW5rIHRlc3Qgc2hvd3MgdXMgdGhhdCB0aGVyZSBzZWVtcyB0byBiZSBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UsIHdoaWNoIHdlJ2xsIGludmVzdGlnYXRlIGZ1cnRoZXIgd2l0aCBzdHJhdGlmaWNhdGlvbi4NCg0KDQojIyBTdHJhdGlmaWNhdGlvbg0KVG8gZmluZCBvdXQgaW4gd2hpY2ggd2F5IHRoZSBlcmEgaW5mbHVlbmNlcyBzdXJ2aXZhbCwgd2UnbGwgcGxvdCB0aGUgZGlzdGluY3Rpb24uDQpgYGB7cn0NCmdnc3VydnBsb3Qoc3VydmZpdChTdXJ2KGxlbmd0aF9yZWlnbiwgZXZlbnQpIH5FcmEsIGRhdGE9ZW1wZXJvcnMpLCBwdmFsID0gVFJVRSwgcmlzay50YWJsZSA9IFRSVUUsIG1haW4gPSAiRW1wZXJvcnMnIHN1cnZpdmFsIGJ5IEVyYSAobG9nLWxvZykiLCBmdW49ImNsb2dsb2ciKQ0KDQpgYGANCldlIGNhbiBzZWUgYWxyZWFkeSB0aGF0IHRoZXJlIGlzIGEgc3RlZXAgZGlmZmVyZW5jZSBpbiBzdXJ2aXZhbCByYXRlIGlmIHdlIGRpc3Rpbmd1aXNoIHRoZSAyIGVyYXM6IGVtcGVyb3JzIHdlcmUgbXVjaCBsaWtlbHkgdG8gZ2V0IGtpbGxlZCBpbiB0aGUgUHJpbmNpcGF0ZSBlcmEgdGhhbiBpbiB0aGUgRG9taW5hdGUgZXJhLiBUaGlzIGZpbmRpbmcgaXMgcmVpbmZvcmNlZCBieSB0aGUgcGFyYWxsZWxpc20gb2YgYm90aCBjdXJ2ZXMsIGluIGxvZy1sb2cgZm9ybWF0Lg0KDQpUaGlzIHJlc3VsdCBpcyByYXRoZXIgc3VycHJpc2luZywgYXMgd2Uga25vdyB0aGF0IHRoZSBQcmluY2lwYXRlIGVyYSB3YXMgY2hhcmFjdGVyaXNlZCBieSBhbiBlZmZvcnQgb24gdGhlIHBhcnQgb2YgdGhlIGVtcGVyb3JzIHRvIHByZXNlcnZlIHRoZSBpbGx1c2lvbiBvZiBjb250aW51YW5jZSBvZiB0aGUgUm9tYW4gUmVwdWJsaWMuDQoNCg0KV2UnbGwgaW52ZXN0aWdhdGUgb24gb3RoZXIgcG9zc2libGUgZGlzdGluY3Rpb25zIHRoYXQgbWlnaHQgaW5mbHVlbmNlIHRoZSByaXNrIGZvciBlbXBlcm9ycyB0byBnZXQga2lsbGVkLg0KRm9yIGV4YW1wbGUsIHdlIGNhbiB3b25kZXIgaWYgdGhlIHdheSB0aGUgZW1wZXJvciBhY2hpZXZlZCBoaXMgcG9zaXRpb24gKFN1Y2Nlc3Npb24pIGluZmx1ZW5jZXMgdGhlIHJpc2suIFRoZXJlIGFyZSB0b28gbWFueSBjYXRlZ29yaWVzLCBzbyBsZXQncyBmaXJzdCBncm91cCBzb21lIG9mIHRoZW0gdG9nZXRoZXIuDQpgYGB7cn0NCmVtcGVyb3JzJFN1Y2Nlc3Npb24yIDwtIGlmZWxzZShlbXBlcm9ycyRTdWNjZXNzaW9uICVpbiUgYygiQXBwb2ludG1lbnQgYnkgQXJteSIsICJBcHBvaW50bWVudCBieSBQcmFldG9yaWFuIEd1YXJkIiksICJBcHBvaW50bWVudCBieSBtaWxpdGFyeSIsIGlmZWxzZShlbXBlcm9ycyRTdWNjZXNzaW9uICVpbiUgYygiQXBwb2ludG1lbnQgYnkgRW1wZXJvciIsICJBcHBvaW50bWVudCBieSBTZW5hdGUiKSwgIkFwcG9pbnRtZW50IGJ5IHN0YXRlIiwgaWZlbHNlKGVtcGVyb3JzJFN1Y2Nlc3Npb24gPT0gIkJpcnRocmlnaHQiLCAiQmlydGhyaWdodCIsIGlmZWxzZShlbXBlcm9ycyRTdWNjZXNzaW9uID09ICJTZWl6ZWQgUG93ZXIiLCAiU2VpemVkIFBvd2VyIiwgICJPdGhlciIpKSkpDQoNCg0Kc3VtbWFyeShjb3hwaChTdXJ2KGxlbmd0aF9yZWlnbiwgZXZlbnQpIH5FcmEgKyBTdWNjZXNzaW9uMiwgZGF0YSA9IGVtcGVyb3JzKSkNCnN1bW1hcnkoY294cGgoU3VydihsZW5ndGhfcmVpZ24sIGV2ZW50KSB+RXJhICsgc3RyYXRhKFN1Y2Nlc3Npb24yKSwgZGF0YSA9IGVtcGVyb3JzKSkNCg0KZ2dzdXJ2cGxvdChzdXJ2Zml0KFN1cnYobGVuZ3RoX3JlaWduLCBldmVudCkgfiBTdWNjZXNzaW9uMiwgZGF0YSA9IGVtcGVyb3JzKSwgcHZhbCA9IFRSVUUsIHB2YWwuY29vcmQgPSBjKDMwLDAuOCksIG1haW4gPSAiRW1wZXJvcnMnIHN1cnZpdmFsIGJ5IHdheSBvZiBhY2Nlc3NpbmcgcG93ZXIiLCBsZWdlbmQubGFicyA9IGMoIkFwcG9pbnRtZW50IGJ5IG1pbGl0YXJ5IiwgIkFwcG9pbnRtZW50IGJ5IHN0YXRlIiwgIkJpcnRocmlnaHQiLCAiT3RoZXIiLCAiU2VpemVkIFBvd2VyIikpDQpgYGANCg0KVGhlIGZpcnN0IGRldGFpbGVkIG1vZGVsLCBkaXNwbGF5cyBpbnRlcmVzdGluZyByZWxldmFuY2Ugd2l0aCBsb3cgcC12YWx1ZXMgaW5kaWNhdGluZyB0aGF0IGRpZmZlcmVudCBzdWNjZXNzaW9uIG1ldGhvZHMgaW1wbHkgZGlmZmVyZW50IHJpc2tzLCB3aGlsZSB0aGUgc2Vjb25kIG1vcmUgZ2VuZXJhbCBtb2RlbCBkb2VzIG5vdCBvZmZlciBhIGNyZWRpYmxlIHAtdmFsdWUgdG8gYmUgZm9sbG93ZWQgYXMtaXMuIA0KDQpJbmRlZWQsIHBsb3R0aW5nIHRoZSBDb3ggaW4gY2xvZ2xvZyB3ZSBjYW4gc2VlIHRoYXQgdGhlIGxpbmVzIGFyZSBub3QgcGFycmFsZWwsIHdoaWNoIGlzIHdoeSB0aGUgbW9kZWwgYXMgYSB3aG9sZSBpcyBub3Qgc28gZWZmZWN0aXZlLg0KYGBge3J9DQpnZ3N1cnZwbG90KHN1cnZmaXQoU3VydihsZW5ndGhfcmVpZ24sIGV2ZW50KSB+IEVyYSArIFN1Y2Nlc3Npb24yLCBkYXRhID0gZW1wZXJvcnMpLCBwdmFsID0gVFJVRSwgcHZhbC5jb29yZCA9IGMoMzAsLTIpLCBmdW49ImNsb2dsb2ciLCBsZWdlbmQubGFicyA9IGMoIkRvbWluYXRlL0FwcG9pbnRtZW50IGJ5IG1pbGl0YXJ5IiwgIkRvbWluYXRlL0FwcG9pbnRtZW50IGJ5IHN0YXRlIiwgIkRvbWluYXRlL0JpcnRocmlnaHQiLCAiRG9taW5hdGUvT3RoZXIiLCAiRG9taW5hdGUvU2VpemVkIFBvd2VyIiwiUHJpbmNpcGF0ZS9BcHBvaW50bWVudCBieSBtaWxpdGFyeSIsICJQcmluY2lwYXRlL0FwcG9pbnRtZW50IGJ5IHN0YXRlIiwgIlByaW5jaXBhdGUvQmlydGhyaWdodCIsICJQcmluY2lwYXRlL090aGVyIiwgIlByaW5jaXBhdGUvU2VpemVkIFBvd2VyIikpDQpgYGANCg0KV2UgY2FuIGNvbmNsdWRlIGZyb20gdGhpcyAobm9uZSBvZiB0aGUgbGluZXMgYXJlIHBhcmFsbGVsKSB0aGF0IHRoZSBtb2RlbCBpcyBub3QgYWNjdXJhdGUgYmVjYXVzZSB0aGUgQ294IGFzc3VtcHRpb24gb2YgcHJvcG9ydGlvbmFsaXR5IG9mIGhhemFyZHMgaXMgbm90IHJlc3BlY3RlZDogd2Ugd2lsbCBub3QgYmUgYWJsZSB0byB1c2UgdGhlIGNvZWZmaWNpZW50cyBmcm9tIHRoZSBtb2RlbCwgYnV0IHdlIG1heSBzdGlsbCBjb25zaWRlciBTdWNjZXNzaW9uIGFzIGEgc29tZXdoYXQgaW50ZXJlc3RpbmcgdmFyaWFibGUsIHNpbmNlIGFkZGluZyB0aGUgU3VjY2Vzc2lvbiB0byB0aGUgRXJhIGltcHJvdmVzIHRoZSBwLXZhbHVlLg0KDQoNCg0KDQpXZSBjYW4gd29uZGVyIGlmIHRoZSBfX0VtcGVyb3IncyBvcmlnaW5fXyBwbGF5cyBhIHJvbGUgaW4gaGlzIHBvcHVsYXJpdHkgaW4gUm9tZSBhbmQgdGhlcmVmb3JlIGhpcyBzdXJ2aXZhbCBsaWtlbGlob29kLg0KYGBge3J9DQp0YWJsZShlbXBlcm9ycyRCaXJ0aC5Qcm92aW5jZSwgZW1wZXJvcnMkZXZlbnQpDQpgYGANCkhvd2V2ZXIsIHRoZSBjYXRlZ29yaWVzIGFyZSBhIGxpdHRsZSB0b28gbnVtZXJvdXMgYW5kIHRoZXJlZm9yZSB0b28gcmVzdHJpY3RpdmUgdG8gYmUgdmVyeSBpbmRpY2F0aXZlLCBzbyB3ZSdsbCBwcm9jZWVkIHRvIHNvbWUgZ3JvdXBpbmcgaW4gb3JkZXIgdG8gaGF2ZSB3aWRlciBncm91cHMuDQpgYGB7cn0NCmVtcGVyb3JzJEJpcnRoLlJlZ2lvbiA8LSBpZmVsc2UoZW1wZXJvcnMkQmlydGguUHJvdmluY2UgJWluJSBjKCJBZnJpY2EiLCAiTGlieWEiLCAiTWF1cmV0YW5pYSIpLCAiQWZyaWNhIiwgaWZlbHNlKGVtcGVyb3JzJEJpcnRoLlByb3ZpbmNlICVpbiUgYygiR2FsbGlhIEx1Z2R1bmVuc2lzIiwgIkdhbGxpYSBOYXJib25lbnNpcyIpLCAiR2F1bCIsIGlmZWxzZShlbXBlcm9ycyRCaXJ0aC5Qcm92aW5jZSAlaW4lIGMoIkhpc3BhbmlhIiwgIkhpc3BhbmlhIEJhZXRpY2EiKSwgIlNwYWluIiwgaWZlbHNlKGVtcGVyb3JzJEJpcnRoLlByb3ZpbmNlICVpbiUgYygiRGFjaWEgQXVyZWxpYW5hIiwgIkRhbG1hdGlhbiIsICJNb2VzaWEiLCAiTW9lc2lhIFN1cGVyaW9yIiwgIlBhbm5vbmlhIiwgIlBhbm5vbmlhIEluZmVyaW9yIiwgIlRocmFjZSIpLCAiRWFzdCBFdXJvcGUiLCBpZmVsc2UoZW1wZXJvcnMkQmlydGguUHJvdmluY2UgJWluJSBjKCJQaHJ5Z2lhIiwgIlN5cmlhIiksICJBc2lhIE1pbm9yIiwgaWZlbHNlKGVtcGVyb3JzJEJpcnRoLlByb3ZpbmNlID09ICJJdGFsaWEiLCAiSXRhbGlhIiwgIlVua25vd24iKSkpKSkpDQp0YWJsZShlbXBlcm9ycyRCaXJ0aC5SZWdpb24sIGVtcGVyb3JzJGV2ZW50KQ0KYGBgDQpJdCB3aWxsIGJlIGVhc2llciB0byB3b3JrIHdpdGggNyBsZXZlbHMgdGhhbiAxOC4NCmBgYHtyfQ0KcmVnaW9uIDwtIHN1cnZmaXQoU3VydihsZW5ndGhfcmVpZ24sIGV2ZW50KSB+QmlydGguUmVnaW9uLCBkYXRhPWVtcGVyb3JzKQ0Kc3VtbWFyeShyZWdpb24pDQpnZ3N1cnZwbG90KHJlZ2lvbiwgcHZhbCA9IFRSVUUsIHB2YWwuY29vcmQgPSBjKDMwLDAuOSksIHBhbGV0dGUgPSBjKGMoIiMwMEVFMDAiLCAiIzAwMDBFRSIsICIjQ0QwMDAwIiwgIiNCRjNFRkYiLCAiI0VFRUUwMCIsICIjMDBGRkZGIiwgIiNFRTlBMDAiKSksIG1haW4gPSAiRW1wZXJvcnMnIHN1cnZpdmFsIGJ5IFByb3ZpbmNlIG9mIG9yaWdpbiIsIGxlZ2VuZC5sYWJzID0gYygiQWZyaWNhIiwiQXNpYSBNaW5vciIsICJFYXN0IEV1cm9wZSIsICJHYXVsIiwgIkl0YWxpYSIsICJTcGFpbiIsICJVbmtub3duIikpDQpgYGANCg0KSGVyZSB3ZSBjYW4gc2VlIHRoZSBzdXJ2aXZhbCBjdXJ2ZXMgYmFzZWQgb24gdGhlIHJlZ2lvbiBvZiBvcmlnaW4uIFRoZXJlIGlzIGRlZmluaXRpdmVseSBzb21lIGltcGFjdCwgYmFzZWQgb24gdGhlIGxvdyBwLXZhbHVlLCBidXQgdGhlIGxpbmVzIHRoZW1zZWx2ZXMgYXJlIG5vdCB0aGF0IGluZGljYXRpdmUgKGluIGxvZy1sb2csIHRoZXkgYXJlIG5vdCBwYXJhbGxlbCksIHNvIHdlIHdvbid0IGJlIHVzaW5nIHRoZSBpbmZvcm1hdGlvbiBhcyBzdWNoLg0KDQoNCg0KDQpMb29raW5nIGF0IHRoZSBfX2FnZSBlbXBlcm9ycyBoYWQgYXQgdGhlIHRpbWUgdGhleSB0b29rIHBvd2VyX18uIEFzIGZvciB0aGUgb3JpZ2luLCB3ZSdsbCBoYXZlIHRvIGNhdGVnb3JpemUgZmlyc3QuDQpgYGB7cn0NCmVtcGVyb3JzJGFnZV9hY2Nlc3Npb24yIDwtIGlmZWxzZShlbXBlcm9ycyRhZ2VfYWNjZXNzaW9uPjYwLCAiNjErIiwgaWZlbHNlKGVtcGVyb3JzJGFnZV9hY2Nlc3Npb24+NDAsICI0MS02MCIsIGlmZWxzZShlbXBlcm9ycyRhZ2VfYWNjZXNzaW9uPjMwLCAiMzEtNDAiLCBpZmVsc2UoZW1wZXJvcnMkYWdlX2FjY2Vzc2lvbjwzMCwgIjMwLSIsICJVbmtub3duIikpKSkNCmBgYA0KDQpgYGB7cn0NCmFnZV9hY2Nlc3MgPC0gc3VydmZpdChTdXJ2KGxlbmd0aF9yZWlnbiwgZXZlbnQpIH5hZ2VfYWNjZXNzaW9uMiwgZGF0YT1lbXBlcm9ycykNCnN1bW1hcnkoYWdlX2FjY2VzcykNCmdnc3VydnBsb3QoYWdlX2FjY2VzcywgcHZhbCA9IFRSVUUsIHB2YWwuY29vcmQgPSBjKDMwLDAuNiksIG1haW4gPSAiRW1wZXJvcnMnIHN1cnZpdmFsIGJ5IGFnZSBhdCBiZWdpbm5pbmcgb2YgcmVpZ24gaW4gbG9nLWxvZyIsIGxlZ2VuZC5sYWJzID0gYygiMzAgJiBsZXNzIiwgIjMxLTQwIiwgIjQxLTYwIiwgIjYxIGFuZCBhYm92ZSIpLCBmdW49ImNsb2dsb2ciKQ0KYGBgDQoNCkhlcmUgdGhlIHAtdmFsdWUgaXMgbXVjaCBsb3dlciBldmVuLCBhbmQgdGhlIGxpbmVzIGJhcmVseSBjcm9zcyB3aGljaCBpbXBsaWVzIHRoYXQgd2UncmUgY2xvc2VyIHRvIGEgbW9kZWwgd2UgY291bGQgdXNlLg0KDQojIyBDb3ggcmVncmVzc2lvbiBNb2RlbA0KYGBge3J9DQpsaWJyYXJ5KG5ldHdvcmtEMykNCmBgYA0KXyoqRGlzdHJpYnV0aW9uIG9mIGVtcGVyb3JzIGJ5IER5bmFzdHkqKl8NCmBgYHtyfQ0Kc2ltcGxlTmV0d29yayhzZWxlY3QoZW1wZXJvcnMsIE5hbWUsIER5bmFzdHkpLCBmb250U2l6ZSA9IDE4LCBub2RlQ29sb3VyID0gInJlZCIpDQpgYGANCg0KVG8gZmluZCBvdXQgdGhlIGRpZmZlcmVuY2Ugb2Ygc3Vydml2YWwgY2hhbmNlIGJldHdlZW4gZHluYXN0aWVzLCB3ZSBjYW4gdXNlIHRoZSBDb3ggbW9kZWwuDQpUaGlzIHdpbGwgY29tcGFyZSBhbGwgZHluYXN0aWVzIHdpdGggdGhlIGZpcnN0IG9uZS4gQnkgZGVmYXVsdCwgdGhlIGZpcnN0IG9uZSBpbiBhbHBoYWJldGljYWwgb3JkZXIgd2lsbCBiZSB1c2VkIGZvciBjb21wYXJpc29uLiBIZXJlLCB3ZSdsbCBjaGFuZ2UgdGhlIG9yZGVyLCBzbyB0aGF0IHRoZSBGbGF2aWFuIGR5bmFzdHkgY29tZXMgZmlyc3QsIGFzIGl0IGlzIHRoZSBvbmx5IG9uZSB0aGF0IGhhZCBhIDUwLTUwIHN1cnZpdmFsIHJhdGUuDQpgYGB7cn0NCmVtcGVyb3JzJER5bmFzdHkgPSBmYWN0b3IoZW1wZXJvcnMkRHluYXN0eSxsZXZlbHMoZW1wZXJvcnMkRHluYXN0eSlbYygyLDEsMzo4KV0pDQpzdW1tYXJ5KGNveHBoKGZvcm11bGEgPSBTdXJ2KGxlbmd0aF9yZWlnbiwgZXZlbnQpIH4gRHluYXN0eSwgZGF0YSA9IGVtcGVyb3JzKSkNCmBgYA0KVGhpcyBzaG93cyB1cyBmaXJzdCB0aGF0IHRoZSBpbmZsdWVuY2Ugb2YgZHluYXN0eSBvbiBzdXJ2aXZhbCBjaGFuY2VzIGlzIHNpZ25pZmljYW50IChwLXZhbHVlIDAuMDI0OTMpLCBhbmQgdGhhdCBjb21wYXJlZCB0byB0aGUgRmxhdmlhbiBkeW5hc3R5LCBlbXBlcm9ycyBpbiB0aGUgQ29uc3RhbnRpbmlhbiBkeW5hc3R5IGhhZCAwLjMxIHRpbWVzIG1vcmUgY2hhbmNlIHRvIHN1cnZpdmUgKCsvLSAzLjE5KS4NClN0aWxsIGNvbXBhcmVkIHRvIHRoZSBGbGF2aWFuLCBOZXJ2YS1BbnRvbmluZSBoYWQgYSB2ZXJ5IHNtYWxsIGNoYW5jZSB0byBiZSBraWxsZWQgYXQgMC4wODQxICgrLy0gMS4xODkpLg0KDQoNCg0KIyMgTXVsdGlwbGUgQ292YXJpYXRlcw0KTm93LCBsZXQncyBsb29rIGF0IHRoZSB0aHJlZSB2YXJpYWJsZXMgb2YgKlN1Y2Nlc3Npb24qLCAqRXJhKiBhbmQgKkFnZSBhdCBhY2Nlc3Npb24qICh3aXRoIHJlZGVmaW5lZCBjYXRlZ29yaWVzIGFzIHNlZW4gYWJvdmUpLCBhbmQgdHJ5IHRvIGlkZW50aWZ5IHRoZSBiZXN0IGV4cGxpY2F0aXZlIG1vZGVsIGZvciBlbXBlcm9ycycgc3Vydml2YWwuDQoNClRvIHN0dWR5IHRoZSBjb3ZhcmlhdGVzLCB3ZSBuZWVkIHRvIHVzZSB0aGUgQ294IHByb3BvcnRpb25hbCBoYXphcmRzIHJlZ3Jlc3Npb24gbW9kZWwuDQpUaGUgbW9kZWwsIGFuZCB0aGUgc3RlcHdpc2UgYWxnb3JpdGhtLCBvbmx5IHdvcmtzIHdpdGggbm9uLW1pc3NpbmcgdmFsdWVzLCBzbyBJJ2xsIG1ha2UgYSBzZWxlY3Rpb24gb2YgdGhlIHZhcmlhYmxlcyB0byBjb25zaWRlciwgYW5kIHJlbW92ZSB0aGUgcm93cyB3aXRoIG1pc3NpbmcgdmFsdWVzLg0KYGBge3J9DQpzZWxlY3Rpb24gPC0gZW1wZXJvcnMgJT4lIHNlbGVjdChjKGxlbmd0aF9yZWlnbiwgZXZlbnQsIFN1Y2Nlc3Npb24yLCBFcmEsIGFnZV9hY2Nlc3Npb24yKSkNCnNlbGVjdGlvbiA8LSBmaWx0ZXIoc2VsZWN0aW9uLCBjb21wbGV0ZS5jYXNlcyhzZWxlY3Rpb24pKQ0KDQphbGxfdmFyaWFibGVzIDwtIGNveHBoKFN1cnYobGVuZ3RoX3JlaWduLCBldmVudCkgfiAuICwgZGF0YSA9IHNlbGVjdGlvbikNCg0KQUlDIDwtIHN0ZXAoYWxsX3ZhcmlhYmxlcywgZGlyZWN0aW9uPSJmb3J3YXJkIikNCnN1bW1hcnkoQUlDKQ0KDQpnZ3N1cnZwbG90KHN1cnZmaXQoQUlDKSwgbWFpbj0iU3Vydml2YWwgZnVuY3Rpb24gKHByZWRpY3Rpb24pIiwgY29sb3I9ImJsdWUiKQ0KYGBgDQoNClRoZSByZXN1bHQgb2YgdGhlIENveCBtb2RlbCBhbmQgc3RlcCBhbGdvcml0aG0gKHdoaWNoIHdlbnQgdGhyb3VnaCAxNiBpdGVyYXRpb25zIHN0YXJ0aW5nIHdpdGggbm8gdmFyaWFibGUsIHRoZW4gYWRkaW5nIHRoZW0gb25lIGJ5IG9uZSkgaXMgYSBwcmVkaWN0b3IgYmFzZWQgb24gOCB2YXJpYWJsZXMsIHdpdGggbG93IHAtdmFsdWVzIG9uIGFsbCB0ZXN0cywgaW5kaWNhdGluZyB0aGF0IHdlIGNhbiBzYWZlbHkgZGlzY2FyZCB0aGUgbnVsbCBoeXBvdGhlc2lzICh0aGF0IHRoZSA4IHZhcmlhYmxlcyBjaG9zZW4gYnkgdGhlIHN0ZXB3aXNlIGFsZ29yaXRobSBkbyBub3Qgc2lnbmlmaWNhbnRseSBpbXBhY3QgY2hhbmNlcyBvZiBzdXJ2aXZhbCkuDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KVGhpcyBnaXZlcyBlbm91Z2ggY29uZmlkZW5jZSB0byBjaG9zZSB0aGUgbW9kZWwgZm9yIHRoZSBsYXN0IHN0ZXAgb2YgdGhpcyBwYXBlcjoNCiMgUHJlZGljdGlvbg0KVG8gbWFrZSBhIHByZWRpY3Rpb24sIHdlIG5lZWQgdG8gc3BsaXQgdGhlIGRhdGEgaW4gMiBwYXJ0cywgb25lIHRvIHRyYWluIHRoZSBtb2RlbCwgdGhlIG90aGVyIHRvIHRlc3QgaXQuDQpgYGB7cn0NCiMjIDc1JSBvZiB0aGUgc2FtcGxlIHNpemUNCnNtcF9zaXplIDwtIGZsb29yKDAuNyAqIG5yb3coZW1wZXJvcnMpKQ0KDQojIyBzZXQgdGhlIHNlZWQgdG8gbWFrZSB5b3VyIHBhcnRpdGlvbiByZXByb2R1Y3RpYmxlDQpzZXQuc2VlZCgyNCkNCnRyYWluX2luZCA8LSBzYW1wbGUoc2VxX2xlbihucm93KGVtcGVyb3JzKSksIHNpemUgPSBzbXBfc2l6ZSkNCg0KdHJhaW4gPC0gZW1wZXJvcnNbdHJhaW5faW5kLCBdDQp0ZXN0IDwtIGVtcGVyb3JzWy10cmFpbl9pbmQsIF0NCmBgYA0KSGVyZSBJJ3ZlIGRlY2lkZWQgdG8gdHJhaW4gdGhlIG1vZGVsIG9uIDgwJSBvZiB0aGUgZGF0YSAoNDYgZW1wZXJvcnMpLCBhbmQgbWFrZSB0aGUgcHJlZGljdGlvbiBvbiB0aGUgMjAgbGVmdC4NCg0KDQpMZXQncyBvbmx5IGtlZXAgdGhlIHVzZWZ1bCB2YXJpYWJsZXMgaW4gdGhlIHR3byBkYXRhLmZyYW1lcywgYW5kIHJlbW92ZSB0aGUgcm93cyB3aXRoIE5BIHZhbHVlcyBpbiB0cmFpbi4NCmBgYHtyfQ0KdGVzdCA8LSB0ZXN0ICU+JSBzZWxlY3QoTmFtZSwgU3VjY2Vzc2lvbjIsIEVyYSwgYWdlX2FjY2Vzc2lvbjIsIGxlbmd0aF9yZWlnbiwgZXZlbnQpDQp0cmFpbiA8LSB0cmFpbiAlPiUgc2VsZWN0KFN1Y2Nlc3Npb24yLCBFcmEsIGFnZV9hY2Nlc3Npb24yLCBsZW5ndGhfcmVpZ24sIGV2ZW50KQ0KdHJhaW4gPC0gZmlsdGVyKHRyYWluLCBjb21wbGV0ZS5jYXNlcyh0cmFpbikpDQoNCm1vZGVsIDwtIGNveHBoKFN1cnYobGVuZ3RoX3JlaWduLCBldmVudCkgfiAuICwgZGF0YSA9IHRyYWluKQ0KDQptb2RlbHMgPC0gc3RlcChtb2RlbCwgZGlyZWN0aW9uPSJmb3J3YXJkIikNCmBgYA0KDQpOb3cgdGhhdCB0aGUgbW9kZWwgaXMgdHJhaW4sIHdlIGp1c3QgbmVlZCB0byB1c2UgaXQgdG8gZ2VuZXJhdGUgdGhlIHByZWRpY3Rpb25zLCBhbmQgY29tcGFyZSB0aGUgcHJlZGljdGVkIHZhbHVlIHdpdGggdGhlIHRydWUgdmFsZSBpbiB0aGUgImV2ZW50IiBjb2x1bW4uDQpgYGB7cn0NCnRlc3QkcHJlZGljdGVkX3ZhbHVlIDwtIGlmZWxzZShwcmVkaWN0KG1vZGVscywgbmV3ZGF0YT10ZXN0LCB0eXBlID0gImV4cGVjdGVkIikgPiAwLjUsIDEsMCkNCmxpYnJhcnkoUk9DUikNCnJlc3VsdHMgPC0gUk9DUjo6cHJlZGljdGlvbih0ZXN0JGV2ZW50LCB0ZXN0JHByZWRpY3RlZF92YWx1ZSkNCnBsb3QodW5saXN0KHJlc3VsdHNAdHApLCB1bmxpc3QocmVzdWx0c0BmcCksIHR5cGU9ImwiKQ0KDQpwbG90KHBlcmZvcm1hbmNlKHJlc3VsdHMsIG1lYXN1cmUgPSAidHByIiwgeC5tZWFzdXJlID0gImZwciIpKQ0KYGBgDQoNCg0K